package io.github.dunwu.javacore.jdk8.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

/**
 * @author Benjamin Winterberg
 */
public class Streams12 {

	public static void main(String[] args) {
		List<String> strings = Arrays.asList("a1", "a2", "b1", "c2", "c1");

		// test1();
		// test2(strings);
		test3(strings);
		// test4();
	}

	private static void test3(List<String> strings) {
		strings.parallelStream().filter(s -> {
			System.out.format("filter:  %s [%s]\n", s, Thread.currentThread().getName());
			return true;
		}).map(s -> {
			System.out.format("map:     %s [%s]\n", s, Thread.currentThread().getName());
			return s.toUpperCase();
		}).sorted((s1, s2) -> {
			System.out.format("sort:    %s <> %s [%s]\n", s1, s2, Thread.currentThread().getName());
			return s1.compareTo(s2);
		}).forEach(s -> System.out.format("forEach: %s [%s]\n", s, Thread.currentThread().getName()));
	}

	private static void test4() {
		List<String> values = new ArrayList<>(100);
		for (int i = 0; i < 100; i++) {
			UUID uuid = UUID.randomUUID();
			values.add(uuid.toString());
		}

		// sequential

		long t0 = System.nanoTime();

		long count = values.parallelStream().sorted((s1, s2) -> {
			System.out.format("sort:    %s <> %s [%s]\n", s1, s2, Thread.currentThread().getName());
			return s1.compareTo(s2);
		}).count();
		System.out.println(count);

		long t1 = System.nanoTime();

		long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
		System.out.println(String.format("parallel sort took: %d ms", millis));
	}

	private static void test2(List<String> strings) {
		strings.parallelStream().filter(s -> {
			System.out.format("filter:  %s [%s]\n", s, Thread.currentThread().getName());
			return true;
		}).map(s -> {
			System.out.format("map:     %s [%s]\n", s, Thread.currentThread().getName());
			return s.toUpperCase();
		}).forEach(s -> System.out.format("forEach: %s [%s]\n", s, Thread.currentThread().getName()));
	}

	private static void test1() {
		// -Djava.util.concurrent.ForkJoinPool.common.parallelism=5

		ForkJoinPool commonPool = ForkJoinPool.commonPool();
		System.out.println(commonPool.getParallelism());
	}

}
